﻿using System;
using System.Collections.Generic;
using System.Text;
using CodePlex.Resourceful;
using System.Xml;
using System.IO;
using CodePlex.Resourceful.Amazon.S3;

namespace CodePlex.Resourceful.Microsoft.Azure
{

    public class AzureBlobStorageConnection : BaseAzureConnection<AzureBlobStorageClient>
    {

        public AzureBlobStorageConnection(AzureBlobStorageClient client)
            : base(client)
        {

        }

        public Uri GetContainerUri(string containerName)
        {
            return this.Client.GetContainerUri(containerName);
        }
        public Uri GetBlobUri(string containerName, string blobName)
        {
            return this.Client.GetBlobUri(containerName, blobName);
        }










        public bool IsContainerPresent(string containerName)
        {
            ClientResponse response = this.Client.GetContainerProperties(containerName);
            return response.HttpStatus.Equals(HttpStatus.OK);
        }
        public bool IsBlobPresent(string containerName, string blobName)
        {
            ClientResponse response = this.Client.GetBlobMetadata(containerName, blobName);
            return response.HttpStatus.Equals(HttpStatus.OK);
        }



        public ContainerListing ListContainers()
        {

            ClientResponse response = this.Client.GetContainers(null,null,null);
            Assert(response, HttpStatus.OK);
            return ContainerListing.Parse(response.AsXmlReader());

        }
       
       
        public BlobListing ListBlobs(string containerName)
        {
            return this.ListBlobs(containerName, null, null, null, null);
        }
        public BlobListing ListBlobs(string containerName, string prefix, string marker, string delimiter, int? maxResults)
        {
            ClientResponse response = this.Client.GetBlobs(containerName, prefix, marker, delimiter, maxResults);
            Assert(response, HttpStatus.OK);
            return BlobListing.Parse(response.AsXmlReader());
        }

        public void CreateContainer(string containerName, NameValuePairs metadata)
        {
//The container name must be a valid Domain Name System (DNS) name, conforming to the following naming rules:

//   1. Container names must start with a letter or number, and can contain only letters, numbers, and the dash (-) character.
//   2. Every dash (-) character must be immediately preceded and followed by a letter or number.
//   3. All letters in a container name must be lowercase.
//   4. Container names must be from 3 to 63 characters long.


            ClientResponse response = this.Client.PutContainer(containerName, metadata);
            Assert(response, HttpStatus.Created);
        }


        public NameValuePairs GetContainerProperties(string containerName)
        {
            ClientResponse response = this.Client.GetContainerProperties(containerName);
            Assert(response, HttpStatus.OK);
            return GetMetadata(response,false);

          
        }

     

        public void SetContainerMetadata(string containerName, NameValuePairs metadata)
        {
            ClientResponse response = this.Client.SetContainerMetadata(containerName, metadata,null);
            Assert(response, HttpStatus.OK);
        }
        public bool GetContainerACL(string containerName)
        {
            ClientResponse response = this.Client.GetContainerACL(containerName);
            Assert(response, HttpStatus.OK);

            bool rt = bool.Parse(response.Headers[AzureConstants.Headers.MicrosoftPropertyPublicAccess]);
            return rt;
        }
        public void SetContainerACL(string containerName, bool isPublic)
        {
            ClientResponse response = this.Client.SetContainerACL(containerName, isPublic);
            Assert(response, HttpStatus.OK);
        }


        public void DeleteContainer(string containerName)
        {
            ClientResponse response = this.Client.DeleteContainer(containerName,null);
            Assert(response, HttpStatus.Accepted);
        }

        public void PutBlob(string containerName, string blobName, string blobContents)
        {
            NameValuePairs metadata = new NameValuePairs();
            metadata[HttpHeader.ContentType] = MediaType.TextPlain;

            this.PutBlob(containerName,blobName, metadata,
                delegate { return Utils.ToStream(blobContents); },true,null);
        }
        public void PutBlob(string containerName, string blobName, NameValuePairs metadata, Func20<Stream> blobContentsProvider, bool computeMD5, Action<long> bytesTransferred)
        {
            metadata = metadata ?? new NameValuePairs();
            ClientResponse response = this.Client.PutBlob(containerName, blobName, metadata,
                blobContentsProvider, computeMD5, bytesTransferred,null);
            Assert(response, HttpStatus.Created);
        }

        public void DeleteBlob(string containerName, string blobName)
        {
            ClientResponse response = this.Client.DeleteBlob(containerName, blobName,null);
            Assert(response, HttpStatus.Accepted);
        }
        public string GetBlobAsString(string containerName, string blobName)
        {
            ClientResponse response = this.Client.GetBlob(containerName, blobName, true, null,null);
            Assert(response, HttpStatus.OK);
            return response.AsString();
        }
        public Stream GetBlobAsStream(string containerName, string blobName)
        {
            ClientResponse response = this.Client.GetBlob(containerName, blobName, false, null,null);
            Assert(response, HttpStatus.OK);
            return response.AsStream();
        }

        public NameValuePairs GetBlobProperties(string containerName, string blobName)
        {
            ClientResponse response = this.Client.HeadBlob(containerName, blobName, null);
            Assert(response, HttpStatus.OK);
            return GetMetadata(response,true);
        }
        public NameValuePairs GetBlobMetadata(string containerName, string blobName)
        {
            ClientResponse response = this.Client.GetBlobMetadata(containerName, blobName);
            Assert(response, HttpStatus.OK);
            return GetMetadata(response,false);
        }

        public void SetBlobMetadata(string containerName, string blobName, NameValuePairs metadata)
        {
            ClientResponse response = this.Client.PutBlobMetadata(containerName, blobName, metadata, null);
            Assert(response, HttpStatus.OK);
        }





      
    }

   

}
